#ifndef __M_IM_DATA_H__
#define __M_IM_DATA_H__
#include <iostream>
#include <string>
#include <mutex>
#include <cstdlib>
#include <mysql/mysql.h>

namespace im_sys{
#define DB_HOST "127.0.0.1"
#define DB_USER "root"
#define DB_PASS "123"
#define DB_NAME "db_96"
	static MYSQL *MysqlInit(){
		MYSQL *mysql=mysql_init(NULL);
		if(mysql==NULL){
			std::cout<<"mysql init failed!\n";
			return NULL;
		}if(mysql_real_connect(mysql,DB_HOST,DB_USER,DB_PASS,DB_NAME,0,NULL,0)==NULL){
			std::cout<<"connect mysql server failed: "<<mysql_error(mysql)<<std::endl;
			mysql_close(mysql);
			return NULL;
		}
		if(mysql_set_character_set(mysql,"utf8")!=0){
			std::cout<<"set mysql client character fail!: "<<mysql_error(mysql)<<std::endl;
			mysql_close(mysql);
			return NULL;
		}
		return mysql;
	}
	static void MysqlDestroy(MYSQL *mysql){
		if(mysql!=NULL){
			mysql_close(mysql);
		}
		return ;
	}
	static bool MysqlQuery(MYSQL *mysql,const std::string &sql){
		int ret = mysql_query(mysql,sql.c_str());
		if(ret!=0){
			std::cout<<sql<<std::endl;
			std::cout<<"query failed:"<<mysql_error(mysql)<<std::endl;
			return false;
		}
		return true;
	}
	class UserTable{
		private:
			MYSQL *_mysql;
			std::mutex _mutex;
		public:
			UserTable():_mysql(NULL){
				_mysql=MysqlInit();
				if(_mysql==NULL){
					exit(-1);
				}
			}
			~UserTable(){

				MysqlDestroy(_mysql);
			}
			bool Insert(const std::string &name,const std::string &pass){
				//id,name,pass,status,ctime,stime
#define USER_INSERT "insert im_user values(null,'%s',MD5('%s'),0,now(),now());"
				char sql[4096]={0};
				sprintf(sql,USER_INSERT,name.c_str(),pass.c_str());
				return MysqlQuery(_mysql,sql);
			}
			bool Exists(const std::string &name){
#define USER_EXISTS "select id from im_user where name='%s';"
				char sql[4096]={0};
				sprintf(sql,USER_EXISTS,name.c_str());
				bool ret=MysqlQuery(_mysql,sql);
				if(ret==false){
					return false;
				}
				MYSQL_RES *res=mysql_store_result(_mysql);
				int num=mysql_num_rows(res);
				if(num!=0){
				 mysql_free_result(res);
				 return true;
				}
				mysql_free_result(res);
				return false;
			}
			bool UserPassCheck(const std::string &name,const std::string &pass){
#define USER_CHECK "select id from im_user where name='%s'and pass=MD5('%s');"
				char sql[4096]={0};
				sprintf(sql,USER_CHECK,name.c_str(),pass.c_str());
				bool ret=MysqlQuery(_mysql,sql);
				if(ret==false){
					return false;
				}
				MYSQL_RES *res=mysql_store_result(_mysql);
				int num=mysql_num_rows(res);
				if(num!=0){
					mysql_free_result(res);
					return true;
				}
				mysql_free_result(res);
				return false;
			}
			int Status(const std::string &name){
#define USER_STATUS "select status from im_user where name='%s';"
				char sql[4096]={0};
				sprintf(sql,USER_STATUS,name.c_str());
				bool ret=MysqlQuery(_mysql,sql);
				if(ret==false){
					return false;
				}
				MYSQL_RES* res=mysql_store_result(_mysql);
				int num=mysql_num_rows(res);
				if(num==0){
					mysql_free_result(res);
					return -1;
				}
				MYSQL_ROW row=mysql_fetch_row(res);
				int status=std::stoi(row[0]);
				mysql_free_result(res);
				return status;
			}
			bool Update_Status(const std::string &name,int status){
#define USER_UPDATE_STATUS "update im_user set status=%d,stime=now() where name='%s';"
				char sql[4096]={0};
				sprintf(sql,USER_UPDATE_STATUS,status,name.c_str());
				return MysqlQuery(_mysql,sql);
			}
			bool Update_Passwd(const std::string &name,const std::string &pass){
#define USER_UPDATE_PASS "update im_user set pass=MD5('%s') where name='%s';"
				char sql[4096]={0};
				sprintf(sql,USER_UPDATE_PASS,pass.c_str(),name.c_str());
				return MysqlQuery(_mysql,sql);

			}
	};
}


#endif
